import { useState, useEffect, useMemo, useCallback, useRef, memo, lazy, Suspense } from "react";
import "./Performance.css";

// 懒加载组件
const HeavyComponent = lazy(() => import('./HeavyComponent'));

// 使用 React.memo 优化的组件
const MemoizedListItem = memo(({ item, onItemClick, isSelected }) => {
  console.log(`渲染项目: ${item.id}`);
  
  return (
    <div 
      className={`list-item ${isSelected ? 'selected' : ''}`}
      onClick={() => onItemClick(item.id)}
    >
      <div className="item-avatar">{item.name.charAt(0)}</div>
      <div className="item-info">
        <h3>{item.name}</h3>
        <p>{item.description}</p>
        <span className="item-category">{item.category}</span>
      </div>
      <div className="item-stats">
        <span className="stat">👁 {item.views}</span>
        <span className="stat">❤️ {item.likes}</span>
      </div>
    </div>
  );
});

// 未优化的组件（用于对比）
const RegularListItem = ({ item, onItemClick, isSelected }) => {
  console.log(`渲染未优化项目: ${item.id}`);
  
  return (
    <div 
      className={`list-item ${isSelected ? 'selected' : ''}`}
      onClick={() => onItemClick(item.id)}
    >
      <div className="item-avatar">{item.name.charAt(0)}</div>
      <div className="item-info">
        <h3>{item.name}</h3>
        <p>{item.description}</p>
        <span className="item-category">{item.category}</span>
      </div>
      <div className="item-stats">
        <span className="stat">👁 {item.views}</span>
        <span className="stat">❤️ {item.likes}</span>
      </div>
    </div>
  );
};

// 虚拟滚动组件
function VirtualList({ items, itemHeight, containerHeight, renderItem }) {
  const [scrollTop, setScrollTop] = useState(0);
  const containerRef = useRef();
  
  const visibleStart = Math.floor(scrollTop / itemHeight);
  const visibleEnd = Math.min(
    visibleStart + Math.ceil(containerHeight / itemHeight) + 1,
    items.length
  );
  
  const visibleItems = items.slice(visibleStart, visibleEnd);
  
  const handleScroll = useCallback((e) => {
    setScrollTop(e.target.scrollTop);
  }, []);
  
  return (
    <div className="virtual-list-container">
      <div
        ref={containerRef}
        className="virtual-list-viewport"
        style={{ height: containerHeight }}
        onScroll={handleScroll}
      >
        <div style={{ height: items.length * itemHeight, position: 'relative' }}>
          <div
            style={{
              position: 'absolute',
              top: visibleStart * itemHeight,
              width: '100%'
            }}
          >
            {visibleItems.map((item, index) => (
              <div
                key={item.id}
                style={{ height: itemHeight }}
              >
                {renderItem(item, visibleStart + index)}
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// 性能监控组件
function PerformanceMonitor() {
  const [metrics, setMetrics] = useState({
    renderTime: 0,
    componentCount: 0,
    memoryUsage: 0
  });
  
  useEffect(() => {
    const startTime = performance.now();
    
    // 模拟性能测量
    const measurePerformance = () => {
      const endTime = performance.now();
      const renderTime = endTime - startTime;
      
      // 获取内存使用情况（如果浏览器支持）
      const memoryInfo = performance.memory ? {
        used: Math.round(performance.memory.usedJSHeapSize / 1048576),
        total: Math.round(performance.memory.totalJSHeapSize / 1048576),
        limit: Math.round(performance.memory.jsHeapSizeLimit / 1048576)
      } : null;
      
      setMetrics({
        renderTime: renderTime.toFixed(2),
        componentCount: document.querySelectorAll('[data-reactroot]').length,
        memoryUsage: memoryInfo ? `${memoryInfo.used}MB / ${memoryInfo.total}MB` : '不支持'
      });
    };
    
    const timer = setTimeout(measurePerformance, 100);
    
    return () => clearTimeout(timer);
  }, []);
  
  return (
    <div className="performance-monitor">
      <h4>性能监控</h4>
      <div className="metrics-grid">
        <div className="metric-item">
          <label>渲染时间</label>
          <span>{metrics.renderTime}ms</span>
        </div>
        <div className="metric-item">
          <label>组件数量</label>
          <span>{metrics.componentCount}</span>
        </div>
        <div className="metric-item">
          <label>内存使用</label>
          <span>{metrics.memoryUsage}</span>
        </div>
      </div>
    </div>
  );
}

// React.memo 示例组件
function MemoExample() {
  const [items, setItems] = useState([]);
  const [selectedId, setSelectedId] = useState(null);
  const [useMemoized, setUseMemoized] = useState(true);
  const [renderCount, setRenderCount] = useState(0);
  
  useEffect(() => {
    // 生成测试数据
    const testItems = Array.from({ length: 100 }, (_, i) => ({
      id: i + 1,
      name: `项目 ${i + 1}`,
      description: `这是第 ${i + 1} 个项目的描述信息`,
      category: ['技术', '设计', '产品', '运营'][i % 4],
      views: Math.floor(Math.random() * 1000),
      likes: Math.floor(Math.random() * 500)
    }));
    setItems(testItems);
  }, []);
  
  useEffect(() => {
    setRenderCount(prev => prev + 1);
  });
  
  const handleItemClick = useCallback((id) => {
    setSelectedId(id === selectedId ? null : id);
  }, [selectedId]);
  
  const toggleOptimization = () => {
    setUseMemoized(!useMemoized);
  };
  
  const ListItem = useMemoized ? MemoizedListItem : RegularListItem;
  
  return (
    <div className="example-container">
      <h4>React.memo 优化示例</h4>
      
      <div className="controls">
        <button 
          className={`toggle-btn ${useMemoized ? 'active' : ''}`}
          onClick={toggleOptimization}
        >
          {useMemoized ? '使用 memo 优化' : '未优化版本'}
        </button>
        <div className="render-info">
          <span>父组件渲染次数: {renderCount}</span>
          <span>选中项目: {selectedId || '无'}</span>
        </div>
      </div>
      
      <div className="items-grid">
        {items.slice(0, 10).map(item => (
          <ListItem
            key={item.id}
            item={item}
            onItemClick={handleItemClick}
            isSelected={selectedId === item.id}
          />
        ))}
      </div>
      
      <div className="performance-tip">
        <p>💡 打开浏览器控制台查看渲染日志。使用 memo 优化后，只有选中的项目会重新渲染。</p>
      </div>
    </div>
  );
}

// useMemo 示例组件
function UseMemoExample() {
  const [items, setItems] = useState([]);
  const [filter, setFilter] = useState('');
  const [useMemo, setUseMemo] = useState(true);
  const [calculationCount, setCalculationCount] = useState(0);
  
  useEffect(() => {
    // 生成测试数据
    const testItems = Array.from({ length: 1000 }, (_, i) => ({
      id: i + 1,
      name: `产品 ${i + 1}`,
      price: Math.floor(Math.random() * 1000) + 10,
      category: ['电子产品', '服装', '食品', '图书'][i % 4],
      rating: (Math.random() * 5).toFixed(1)
    }));
    setItems(testItems);
  }, []);
  
  // 昂贵的计算函数
  const expensiveFilter = useCallback((items, filter) => {
    console.log('执行昂贵计算...');
    setCalculationCount(prev => prev + 1);
    
    if (!filter) return items;
    
    return items.filter(item => 
      item.name.toLowerCase().includes(filter.toLowerCase()) ||
      item.category.toLowerCase().includes(filter.toLowerCase())
    );
  }, []);
  
  // 使用 useMemo 缓存计算结果
  const filteredItems = useMemo ? 
    useMemo(() => expensiveFilter(items, filter), [items, filter, expensiveFilter]) :
    expensiveFilter(items, filter);
  
  const totalValue = useMemo ? 
    useMemo(() => filteredItems.reduce((sum, item) => sum + item.price, 0), [filteredItems]) :
    filteredItems.reduce((sum, item) => sum + item.price, 0);
  
  const averageRating = useMemo ? 
    useMemo(() => {
      const sum = filteredItems.reduce((sum, item) => sum + parseFloat(item.rating), 0);
      return filteredItems.length ? (sum / filteredItems.length).toFixed(2) : '0';
    }, [filteredItems]) :
    (() => {
      const sum = filteredItems.reduce((sum, item) => sum + parseFloat(item.rating), 0);
      return filteredItems.length ? (sum / filteredItems.length).toFixed(2) : '0';
    })();
  
  return (
    <div className="example-container">
      <h4>useMemo 优化示例</h4>
      
      <div className="controls">
        <button 
          className={`toggle-btn ${useMemo ? 'active' : ''}`}
          onClick={() => setUseMemo(!useMemo)}
        >
          {useMemo ? '使用 useMemo' : '不使用 useMemo'}
        </button>
        <div className="calculation-info">
          <span>计算次数: {calculationCount}</span>
        </div>
      </div>
      
      <div className="filter-section">
        <input
          type="text"
          placeholder="搜索产品..."
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
          className="filter-input"
        />
      </div>
      
      <div className="stats-section">
        <div className="stat-card">
          <h3>筛选结果</h3>
          <span>{filteredItems.length} 个产品</span>
        </div>
        <div className="stat-card">
          <h3>总价值</h3>
          <span>¥{totalValue.toLocaleString()}</span>
        </div>
        <div className="stat-card">
          <h3>平均评分</h3>
          <span>⭐ {averageRating}</span>
        </div>
      </div>
      
      <div className="performance-tip">
        <p>💡 打开浏览器控制台查看计算日志。使用 useMemo 后，只有依赖项变化时才会重新计算。</p>
      </div>
    </div>
  );
}

// useCallback 示例组件
function UseCallbackExample() {
  const [count, setCount] = useState(0);
  const [items, setItems] = useState([]);
  const [useCallback, setUseCallback] = useState(true);
  
  useEffect(() => {
    const testItems = Array.from({ length: 50 }, (_, i) => ({
      id: i + 1,
      name: `任务 ${i + 1}`,
      completed: Math.random() > 0.5
    }));
    setItems(testItems);
  }, []);
  
  // 不使用 useCallback 的函数
  const handleToggleWithoutCallback = (id) => {
    setItems(prevItems =>
      prevItems.map(item =>
        item.id === id ? { ...item, completed: !item.completed } : item
      )
    );
  };
  
  // 使用 useCallback 的函数
  const handleToggleWithCallback = useCallback((id) => {
    setItems(prevItems =>
      prevItems.map(item =>
        item.id === id ? { ...item, completed: !item.completed } : item
      )
    );
  }, []);
  
  const handleToggle = useCallback ? handleToggleWithCallback : handleToggleWithoutCallback;
  
  const completedCount = items.filter(item => item.completed).length;
  
  return (
    <div className="example-container">
      <h4>useCallback 优化示例</h4>
      
      <div className="controls">
        <button 
          className={`toggle-btn ${useCallback ? 'active' : ''}`}
          onClick={() => setUseCallback(!useCallback)}
        >
          {useCallback ? '使用 useCallback' : '不使用 useCallback'}
        </button>
        <div className="counter-info">
          <span>计数器: {count}</span>
          <button onClick={() => setCount(count + 1)}>增加计数</button>
        </div>
      </div>
      
      <div className="tasks-section">
        <h5>任务列表 ({completedCount}/{items.length} 已完成)</h5>
        <div className="tasks-list">
          {items.slice(0, 10).map(item => (
            <TaskItem
              key={item.id}
              item={item}
              onToggle={handleToggle}
            />
          ))}
        </div>
      </div>
      
      <div className="performance-tip">
        <p>💡 打开浏览器控制台查看渲染日志。使用 useCallback 后，即使父组件重新渲染，子组件也不会不必要的重新渲染。</p>
      </div>
    </div>
  );
}

// 任务项组件（用于 useCallback 示例）
const TaskItem = memo(({ item, onToggle }) => {
  console.log(`渲染任务项: ${item.id}`);
  
  return (
    <div 
      className={`task-item ${item.completed ? 'completed' : ''}`}
      onClick={() => onToggle(item.id)}
    >
      <div className="task-checkbox">
        {item.completed ? '✅' : '⭕'}
      </div>
      <span className="task-name">{item.name}</span>
    </div>
  );
});

// 虚拟滚动示例组件
function VirtualScrollExample() {
  const [items, setItems] = useState([]);
  const [useVirtualScroll, setUseVirtualScroll] = useState(true);
  
  useEffect(() => {
    // 生成大量测试数据
    const testItems = Array.from({ length: 10000 }, (_, i) => ({
      id: i + 1,
      name: `项目 ${i + 1}`,
      description: `这是第 ${i + 1} 个项目的详细描述信息，包含更多的内容来展示虚拟滚动的效果`,
      category: ['技术', '设计', '产品', '运营', '市场', '销售'][i % 6],
      views: Math.floor(Math.random() * 10000),
      likes: Math.floor(Math.random() * 5000)
    }));
    setItems(testItems);
  }, []);
  
  const renderItem = useCallback((item, index) => {
    return (
      <div className="virtual-list-item">
        <div className="item-index">#{index + 1}</div>
        <div className="item-content">
          <h4>{item.name}</h4>
          <p>{item.description}</p>
          <div className="item-meta">
            <span className="category">{item.category}</span>
            <span className="views">👁 {item.views}</span>
            <span className="likes">❤️ {item.likes}</span>
          </div>
        </div>
      </div>
    );
  }, []);
  
  return (
    <div className="example-container">
      <h4>虚拟滚动优化示例</h4>
      
      <div className="controls">
        <button 
          className={`toggle-btn ${useVirtualScroll ? 'active' : ''}`}
          onClick={() => setUseVirtualScroll(!useVirtualScroll)}
        >
          {useVirtualScroll ? '虚拟滚动' : '普通滚动'}
        </button>
        <div className="item-count">
          <span>总项目数: {items.length.toLocaleString()}</span>
        </div>
      </div>
      
      {useVirtualScroll ? (
        <VirtualList
          items={items}
          itemHeight={80}
          containerHeight={400}
          renderItem={renderItem}
        />
      ) : (
        <div className="regular-list" style={{ height: '400px', overflow: 'auto' }}>
          {items.map((item, index) => (
            <div key={item.id} className="virtual-list-item">
              <div className="item-index">#{index + 1}</div>
              <div className="item-content">
                <h4>{item.name}</h4>
                <p>{item.description}</p>
                <div className="item-meta">
                  <span className="category">{item.category}</span>
                  <span className="views">👁 {item.views}</span>
                  <span className="likes">❤️ {item.likes}</span>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}
      
      <div className="performance-tip">
        <p>💡 虚拟滚动只渲染可见区域的项目，大大提高了大量数据时的性能。普通滚动会渲染所有项目。</p>
      </div>
    </div>
  );
}

// 懒加载示例组件
function LazyLoadingExample() {
  const [showHeavyComponent, setShowHeavyComponent] = useState(false);
  const [loadingTime, setLoadingTime] = useState(0);
  
  const loadHeavyComponent = () => {
    const startTime = performance.now();
    setShowHeavyComponent(true);
    
    // 模拟加载时间测量
    setTimeout(() => {
      const endTime = performance.now();
      setLoadingTime((endTime - startTime).toFixed(2));
    }, 100);
  };
  
  return (
    <div className="example-container">
      <h4>懒加载优化示例</h4>
      
      <div className="controls">
        <button onClick={loadHeavyComponent} disabled={showHeavyComponent}>
          加载重型组件
        </button>
        {loadingTime > 0 && (
          <span>加载时间: {loadingTime}ms</span>
        )}
      </div>
      
      <div className="lazy-content">
        {showHeavyComponent ? (
          <Suspense fallback={<div className="loading-fallback">加载中...</div>}>
            <HeavyComponent />
          </Suspense>
        ) : (
          <div className="placeholder">
            <p>点击按钮加载重型组件</p>
            <p>这个组件包含大量数据和复杂计算，使用懒加载可以延迟加载直到需要时</p>
          </div>
        )}
      </div>
      
      <div className="performance-tip">
        <p>💡 懒加载可以减少初始包大小，加快应用启动速度。只有在需要时才加载对应的组件代码。</p>
      </div>
    </div>
  );
}

// 性能对比组件
function PerformanceComparison() {
  const [activeTab, setActiveTab] = useState('memo');
  
  return (
    <div className="example-container">
      <h4>性能优化对比</h4>
      
      <div className="tab-navigation">
        {['memo', 'useMemo', 'useCallback', 'virtual', 'lazy'].map(tab => (
          <button
            key={tab}
            className={`tab-btn ${activeTab === tab ? 'active' : ''}`}
            onClick={() => setActiveTab(tab)}
          >
            {tab === 'memo' && 'React.memo'}
            {tab === 'useMemo' && 'useMemo'}
            {tab === 'useCallback' && 'useCallback'}
            {tab === 'virtual' && '虚拟滚动'}
            {tab === 'lazy' && '懒加载'}
          </button>
        ))}
      </div>
      
      <div className="tab-content">
        {activeTab === 'memo' && <MemoExample />}
        {activeTab === 'useMemo' && <UseMemoExample />}
        {activeTab === 'useCallback' && <UseCallbackExample />}
        {activeTab === 'virtual' && <VirtualScrollExample />}
        {activeTab === 'lazy' && <LazyLoadingExample />}
      </div>
    </div>
  );
}

// 主组件
function Performance() {
  return (
    <div className="performance">
      <h2>React 性能优化</h2>
      
      <PerformanceMonitor />
      <PerformanceComparison />
    </div>
  );
}

export default Performance;